﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.Xml.Linq;

namespace Icst.Leaflike.Config
{
    public class AssemblConfig
    {
        private Configuration _config;
        private Assembly _assembly;

        public AssemblConfig(Assembly assembly) { _assembly = assembly; }

        public AppSettingsSection AppSettings { get { EnsureLoad(); return _config.AppSettings; } }
        public ConnectionStringsSection ConnectionStrings { get { EnsureLoad(); return _config.ConnectionStrings; } }
        public ContextInformation EvaluationContext { get { EnsureLoad(); return _config.EvaluationContext; } }
        public string FilePath { get { EnsureLoad(); return _config.FilePath; } }
        public bool HasFile { get { EnsureLoad(); return _config.HasFile; } }
        public ConfigurationLocationCollection Locations { get { EnsureLoad(); return _config.Locations; } }
        public bool NamespaceDeclared { get { EnsureLoad(); return _config.NamespaceDeclared; } set { EnsureLoad(); _config.NamespaceDeclared = value; } }
        public ConfigurationSectionGroup RootSectionGroup { get { EnsureLoad(); return _config.RootSectionGroup; } }
        public ConfigurationSectionGroupCollection SectionGroups { get { EnsureLoad(); return _config.SectionGroups; } }
        public ConfigurationSectionCollection Sections { get { EnsureLoad(); return _config.Sections; } }
        public ConfigurationSection GetSection(string sectionName) { EnsureLoad(); return _config.GetSection(sectionName); }
        public ConfigurationSectionGroup GetSectionGroup(string sectionGroupName) { EnsureLoad(); return _config.GetSectionGroup(sectionGroupName); }
        public void Save() { EnsureLoad(); _config.Save(); }
        public void Save(ConfigurationSaveMode saveMode) { EnsureLoad(); _config.Save(saveMode); }
        public void Save(ConfigurationSaveMode saveMode, bool forceSaveAll) { EnsureLoad(); _config.Save(saveMode, forceSaveAll); }
        public void SaveAs(string filename) { EnsureLoad(); _config.SaveAs(filename); }
        public void SaveAs(string filename, ConfigurationSaveMode saveMode) { EnsureLoad(); _config.SaveAs(filename, saveMode); }
        public void SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceSaveAll) { EnsureLoad(); _config.SaveAs(filename, saveMode, forceSaveAll); }

        private void EnsureLoad()
        {
            if (_config == null)
            {
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ConfigResolveEventHandler);
                try
                {
                    ExeConfigurationFileMap map = new ExeConfigurationFileMap();
                    map.ExeConfigFilename = _assembly.CodeBase.Replace(@"file:///", string.Empty) + ".config";
                    _config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
                }
                finally { AppDomain.CurrentDomain.AssemblyResolve -= ConfigResolveEventHandler; }
            }
        }
        private Assembly ConfigResolveEventHandler(object sender, ResolveEventArgs args)
        {
            if (_assembly.FullName.Contains(args.Name))
                return Assembly.GetExecutingAssembly();
            else
                return null;
        }
    }
}
